use super::{Task, TaskId};
use alloc::{collections::{BTreeMap, VecDeque}, sync::Arc};
use alloc::task::Wake;
use core::task::Waker;
use crossbeam_queue::ArrayQueue;
use core::task::{Context, Poll};
pub struct Executor {
    task_queue: VecDeque<Task>,  ///存储准备执行的任务 已经准备好的任务
    waiting_tasks: BTreeMap<TaskId, Task>, ///存储返回Poll::Pending的任务。
    /// Arc：Arc是Rust中的一个智能指针类型，它允许多个指针同时指向同一块内存区域。
    /// 多个任务或线程可以通过克隆 Arc 来共享对 wake_queue 的访问，而无需担心数据竞争问题。
    wake_queue: Arc<ArrayQueue<TaskId>>, ///一个task ID的 ArrayQueue，被包装入Arc
    /// wake用来通知运行时，某个任务已经准备好可以重新执行了。
    waker_cache: BTreeMap<TaskId, Waker>, //创建任务后对Waker进行缓存
}
impl Executor {
    pub fn new() -> Self {
        Executor {
            task_queue: VecDeque::new(),
            waiting_tasks: BTreeMap::new(),
            wake_queue: Arc::new(ArrayQueue::new(100)),
            waker_cache: BTreeMap::new(),
        }
    }
    ///将给定的任务添加到task_queue
    pub fn spawn(&mut self, task: Task) {
        self.task_queue.push_back(task)
    }
    ///执行task_queue中的所有任务
    fn run_ready_tasks(&mut self) {
        while let Some(mut task) = self.task_queue.pop_front() {
            let task_id = task.id();
            ///检查warker_cache中是否已存在当前task_id，如果不存在则创建
            if !self.waker_cache.contains_key(&task_id) {
                self.waker_cache.insert(task_id, self.create_waker(task_id));
            }
            let waker = self.waker_cache.get(&task_id).expect("should exist");
            let mut context = Context::from_waker(waker);
            match task.poll(&mut context) {
                Poll::Ready(()) => {
                    // task done -> remove cached waker
                    self.waker_cache.remove(&task_id);
                }
                Poll::Pending => {
                    if self.waiting_tasks.insert(task_id, task).is_some() {
                        panic!("task with same ID already in waiting_tasks");
                    }
                },
            }
        }
    }

    fn create_waker(&self, task_id: TaskId) -> Waker {
        Waker::from(Arc::new(TaskWaker {
            task_id,
            wake_queue: self.wake_queue.clone(),
        }))
    }

    /// 从wake_queue中取出task_id，
    /// 并检查waiting_tasks中是否存在该task_id，
    /// 如果存在则将其从waiting_tasks中移除并添加到task_queue中。
    /// 表示任务已经准备好了，可以重新执行了。
    fn wake_tasks(&mut self) {
        while let Ok(task_id) = self.wake_queue.pop() {
            if let Some(task) = self.waiting_tasks.remove(&task_id) {
                self.task_queue.push_back(task);
            }
        }
    }

    pub fn run(&mut self) -> ! {
        loop {
            self.wake_tasks();
            self.run_ready_tasks();
            self.sleep_if_idle();
        }
    }

    ///在task_queue和wake_queue都为空时执行hlt指令
    // fn sleep_if_idle(&self) {
    //     if self.wake_queue.is_empty() {
    //         ///竞态条件：程序运行到这个地方发生中断！！！！
    //         x86_64::instructions::hlt();
    //     }
    // }

    fn sleep_if_idle(&self) {
        use x86_64::instructions::interrupts::{self, enable_and_hlt};

        interrupts::disable();
        if self.task_queue.is_empty() {
            enable_and_hlt();
        } else {
            interrupts::enable();
        }
    }
}

struct TaskWaker {
    task_id: TaskId,
    wake_queue: Arc<ArrayQueue<TaskId>>,
}

impl TaskWaker {
    fn wake_task(&self) {
        self.wake_queue.push(self.task_id).expect("wake_queue full");
    }
}

impl Wake for TaskWaker {
    fn wake(self: Arc<Self>) {  ///需要Arc的所有权
        self.wake_task();
    }
    fn wake_by_ref(self: &Arc<Self>) {  ///Arc的引用
        self.wake_task();
    }
}